/**
 * chenuu.com
 * 
 * @author  zhaoxu.com@gmail.com
 * @created 2012-11-18
 */
package com.chenuu.webapp.document.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.chenuu.integration.dropbox.api.DropboxAPI;
import com.chenuu.integration.dropbox.model.AccessType;
import com.chenuu.integration.dropbox.model.DropboxEntry;
import com.chenuu.integration.dropbox.session.DropboxSession;
import com.chenuu.webapp.document.domain.DropboxFile;
import com.chenuu.webapp.document.domain.DropboxFileGroup;
import com.chenuu.webapp.document.domain.DuplicateFiles;
import com.chenuu.webapp.document.store.DocumentStore;
import com.dropbox.client2.exception.DropboxException;
import com.google.common.collect.Lists;

/**
 *
 */
@Service("dropboxService")
public class DropboxServiceImpl implements DropboxService {

	protected Log logger = LogFactory.getLog(DropboxServiceImpl.class);

	@Autowired
	private DropboxAPI dropboxAPI;

	@Autowired
	private DocumentStore documentStore;

	@Override
	public DuplicateFiles findDuplicateFiles(DropboxSession session, boolean searchDropbox)
			throws DropboxException {

		if (logger.isDebugEnabled()) {
			logger.debug("查看重复的文档。［searchDropbox=" + searchDropbox + "］");
		}

		if (searchDropbox) {
			Map<String, DropboxEntry> all = new HashMap<String, DropboxEntry>();
			Map<String, List<DropboxFile>> duplicate = new HashMap<String, List<DropboxFile>>();
			loopEntry(session, "/", all, duplicate);

			List<DropboxFileGroup> groupList = new ArrayList<DropboxFileGroup>();
			for (Entry<String, List<DropboxFile>> entry : duplicate.entrySet()) {
				DropboxFileGroup group = new DropboxFileGroup();
				group.setName(entry.getKey());
				group.setFileList(entry.getValue());
				groupList.add(group);
			}
			documentStore.saveUserDuplicateFiles(session.getOAuthToken().getKey(), groupList);
		}

		return documentStore.listUserDuplicateFiles(session.getOAuthToken().getKey());
	}

	private void loopEntry(DropboxSession session, String path, Map<String, DropboxEntry> all,
			Map<String, List<DropboxFile>> re) throws DropboxException {

		if (logger.isDebugEnabled()) {
			logger.debug("扫描目标：" + path);
		}

		boolean list = true;
		String hash = null;
		int fileLimit = -1;
		AccessType accessType = AccessType.APP_FOLDER;

		DropboxEntry entry = dropboxAPI.metadata(session, accessType, path, fileLimit, hash, list);

		if (entry.isDir) {
			if (entry.contents != null) {
				for (DropboxEntry e : entry.contents) {
					if (e.isDir) {
						loopEntry(session, e.path, all, re);
					} else {
						processFile(e, all, re);
					}
				}
			}
		} else {
			// entry is file
			processFile(entry, all, re);
		}
	}

	private void processFile(DropboxEntry entry, Map<String, DropboxEntry> all,
			Map<String, List<DropboxFile>> re) {
		String fileHash = entry.fileName();
		if (all.containsKey(fileHash)) {
			// re

			if (re.containsKey(fileHash)) {
				re.get(fileHash).add(this.toDropboxFile(entry));
			} else {
				re.put(fileHash,
						Lists.newArrayList(this.toDropboxFile(all.get(fileHash)),
								this.toDropboxFile(entry)));
			}
		} else {
			all.put(fileHash, entry);
		}
	}

	private DropboxFile toDropboxFile(DropboxEntry entry) {
		DropboxFile file = new DropboxFile();
		file.setModified(entry.modified.replace(" +0000", ""));
		file.setPath(entry.path);
		file.setSize(entry.size);
		return file;
	}
}
